package cn.yr.common.core.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.yr.common.core.constant.CacheKeyConstants;
import cn.yr.common.core.domain.dto.SysUserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author Lang 1102076808@qq.com
 * @description 缓存
 * @date 2020-06-21 12:11
 */
@Component
public class AuthCacheManager {

	/** 存储用户信息KEY前缀 */
	private static String BASE_KEY = CacheKeyConstants.USER_KEY;
	/** 服务端保存用户信息有效期 代替了token的上记录的有效期 以解决自动刷新token问题
	 * 1. token 有效期 默认30天 达到后需要重新登录 更新前端保存的token
	 * 2. SysUserDto 有效时间 30分钟 超过后代表需要刷新有效时间
	 * 3. redis 有效时间是SysUserDto的两倍 达到SysUserDto有效期刷新redis有效期 以避免每次请求刷新redis
	 * 4. 其实就是模拟session 用户活跃有效期会一直刷新 长时间未活跃（超过redis有效期）后要重新登录 */
	private static int effectiveMinute = 15*60*24;

	@Autowired
	private  RedisTemplate<String,Object> redisTemplate;

	public  void putUser(String uid, SysUserDto sysUserDto) {
		sysUserDto.setExpiredDate(DateUtil.offsetMinute(new Date(),effectiveMinute));
		redisTemplate.opsForValue().set(BASE_KEY+uid,sysUserDto);
		/** 设置redis中过期时间 */
		redisTemplate.expireAt(BASE_KEY+uid,DateUtil.offsetMinute(new Date(),effectiveMinute<<1));
	}

	public  SysUserDto getUser(String uid) {
		Object o = redisTemplate.opsForValue().get(BASE_KEY + uid);
		return BeanUtil.toBean(o,SysUserDto.class);
	}

	public void delUser(String uid){
		redisTemplate.delete(BASE_KEY + uid);
	}

	/**
	 * @Description 刷新token
	 * @author Lang
	 * @Date 2020/6/25 23:14
	 */
	public void refreshUser(String uid){
		SysUserDto sysUserDto = getUser(uid);
		if(ObjectUtil.isEmpty(sysUserDto)||ObjectUtil.isEmpty(sysUserDto.getExpiredDate())){
			throw new RuntimeException("登录失效，请重新登录");
		}
		if(DateUtil.date().isAfter(sysUserDto.getExpiredDate())){
			putUser(uid,sysUserDto);
		}
	}
}
